/**
 * @(#)PropertyFilter.java 2011-10-12
 * 
 * Copyright 2000-2011 by ChinanetCenter Corporation.
 *
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * ChinanetCenter Corporation ("Confidential Information").  You
 * shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement
 * you entered into with ChinanetCenter.
 * 
 */

package com.szf.base.web;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.szf.util.ReflectionUtil;
import com.szf.util.StringUtil;

public class PropertyFilter {
	public enum MatchType {
		EQ("="), LIKE("%value%"), LLIKE("%value"), RLIKE("value%"), LT("<"), GT(">"), LE("<="), GE(
				">="), NE("<>"), IN("IN"), ISNULL("isnull"), ISNOTNULL("isnotnull");
		private String operate;

		MatchType(String operate) {
			this.operate = operate;
		}

		public String getValue() {
			return operate;
		}
	}

	/**
	 * 属性数据类型.
	 */
	public enum PropertyType {
		S(String.class), I(Integer.class), L(Long.class), N(Double.class), D(Date.class), B(
				Boolean.class);

		private Class<?> clazz;

		PropertyType(Class<?> clazz) {
			this.clazz = clazz;
		}

		public Class<?> getValue() {
			return clazz;
		}
	}

	private String propertyName = null;
	private Class<?> propertyType = null;
	private Object propertyValue = null;
	private MatchType matchType = MatchType.EQ;

	public PropertyFilter() {
	}

	/**
	 * @param filterName 比较属性字符串,含待比较的比较类型、属性值类型及属性列表.
	 *            eg. q_loginName_like_s
	 * @param value 待比较的值.
	 */
	public PropertyFilter(final String filterName, final Object value) {

		String[] params = filterName.split("_");
		if (params.length != 4 || !params[0].toUpperCase().equals("Q")) {
			return;
		}
		String matchTypeCode = params[2].toUpperCase();
		String propertyTypeCode = params[3].toUpperCase();
		try {
			matchType = Enum.valueOf(MatchType.class, matchTypeCode);
		}
		catch (RuntimeException e) {
			throw new IllegalArgumentException("控件没有按规则命名,无法得到属性比较类型:" + matchTypeCode);
		}

		boolean isList = false;
		if (propertyTypeCode.length() == 2 && propertyTypeCode.endsWith("L")) {
			isList = true;
			propertyTypeCode = propertyTypeCode.substring(0, 1);
		}

		try {
			propertyType = Enum.valueOf(PropertyType.class, propertyTypeCode).getValue();
		}
		catch (RuntimeException e) {
			throw new IllegalArgumentException("控件没有按规则命名,无法得到属性值类型:" + propertyTypeCode);
		}

		propertyName = params[1];

		//按entity property中的类型将字符串转化为实际类型.
		// PORTAL-54 支持传入数组列表
		if (isList) {
			List<Object> converted = new ArrayList<Object>();
			if (value instanceof Iterable) {
				Iterable<?> ir = (Iterable<?>) value;
				for (Object v : ir) {
					converted.add(ReflectionUtil.convertValue(v, propertyType));
				}
			}
			else if (value.getClass().isArray()) {
				for (Object v : (Object[]) value) {
					converted.add(ReflectionUtil.convertValue(v, propertyType));
				}
			}
			else {
				converted.add(ReflectionUtil.convertValue(value, propertyType));
			}
			this.propertyValue = converted;
		}
		else {
			this.propertyValue = ReflectionUtil.convertValue(value, propertyType);
		}
	}

	/**
	 * 获取比较属性名称列表.
	 */
	public String getPropertyName() {
		return propertyName;
	}

	/**
	 * 获取比较值.
	 */
	public Object getPropertyValue() {
		return propertyValue;
	}

	public Object getPropertyValueWithMatchCheck() {
		Object oriVal = getPropertyValue();
		// 目前只对非空字符串做判断
		if (oriVal instanceof String && StringUtil.isNotEmpty((String) oriVal)) {
			if (MatchType.LIKE.equals(getMatchType())) {
				return "%" + oriVal + "%";
			}
			else if (MatchType.LLIKE.equals(getMatchType())) {
				return "%" + oriVal;
			}
			else if (MatchType.RLIKE.equals(getMatchType())) {
				return oriVal + "%";
			}
		}
		return oriVal;
	}

	/**
	 * 获取比较值.
	 */
	public void setPropertyValue(Object obj) {
		this.propertyValue = obj;
	}

	/**
	 * 获取比较值的类型.
	 */
	public Class<?> getPropertyType() {
		return propertyType;
	}

	/**
	 * 获取比较类型.
	 */
	public MatchType getMatchType() {
		return matchType;
	}

}
